home *** CD-ROM | disk | FTP | other *** search
/ Best Tools for JAVA / Best Tools for JAVA.iso / JAVA_ALL / IDE / SUBARTIC / SUB_ARCT / INPUT / STD_DRAG.JAV < prev    next >
Encoding:
Text File  |  1996-10-04  |  6.9 KB  |  219 lines

  1.     
  2. package sub_arctic.input;
  3.  
  4. import sub_arctic.lib.interactor;
  5. import java.awt.Point;
  6. import java.awt.Rectangle;
  7.  
  8. /** 
  9.  * Utility class containing some standard move-drag filter functions. 
  10.  * Filter functions allow drags to be limited to certain regions or provide
  11.  * various "effects" and transformations of the drag path.  See
  12.  * move_drag_focus_agent for details on how drag filters are applied.
  13.  * 
  14.  * @see sub_arctic.input.move_drag_focus_agent
  15.  * @author Scott Hudson
  16.  */
  17. public class std_drag_filters {
  18.  
  19.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  20.  
  21.   /** 
  22.    * Filter to limit to the inside of a given rectangle. 
  23.    *
  24.    * @param pt the point to be filtered
  25.    * @param lim the rectangle it is limited to
  26.    * @return Point the filtered point
  27.    */
  28.   public static Point limit_to_rect(Point pt, Rectangle lim)
  29.     {
  30.       Point result = new Point(pt.x, pt.y);
  31.  
  32.       if (result.x < lim.x) result.x = lim.x;
  33.       if (result.y < lim.y) result.y = lim.y;
  34.       if (result.x > lim.x + lim.width) result.x = lim.x + lim.width;
  35.       if (result.y > lim.y + lim.height) result.y = lim.y + lim.height;
  36.  
  37.       return result;
  38.     }
  39.  
  40.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  41.  
  42.   /** 
  43.    * Filter to limit to within the bounds of the parent of a given object.
  44.    * Limit can optionally keep the given right and bottom edges of the 
  45.    * object within the parent and/or provide an inset from the parent.  
  46.    *
  47.    * @param pt         the point to be filtered
  48.    * @param of_obj     the object being dragged
  49.    * @param keep_br_in true if we want to keep the bottom right inside the 
  50.    *                   parent (this adds an extra inset)
  51.    * @param x_inset    distance to inset right edge of limit from edge of 
  52.    *                   parent
  53.    * @param y_inset    distance to inset bottom edge of limit from edge of 
  54.    *                   parent
  55.    * @param feature_pt location of feature point being filtered (in local 
  56.    *                   coordinates of of_obj)
  57.    * @return Point the filtered point
  58.    */
  59.   public static Point limit_to_parent(
  60.     Point      pt, 
  61.     interactor of_obj, 
  62.     boolean    keep_br_in, 
  63.     int x_inset,   int y_inset,
  64.     Point      feature_pt)
  65.     {
  66.       int w,h;
  67.       Point result = new Point(pt.x, pt.y);
  68.  
  69.       /* sanity check */
  70.       if (of_obj == null || of_obj.parent() == null)
  71.     return result;
  72.  
  73.       /* compute size of limiting rectangle */
  74.       w = of_obj.parent().w() - x_inset;
  75.       h = of_obj.parent().h() - y_inset;
  76.       if (keep_br_in)
  77.     {
  78.       w -= (of_obj.w() - feature_pt.x) ;
  79.       h -= (of_obj.h() - feature_pt.y);
  80.     }
  81.  
  82.       /* force inside rectangle */
  83.       if (result.x < 0) result.x = 0;
  84.       if (result.y < 0) result.y = 0;
  85.       if (result.x > w) result.x = w;
  86.       if (result.y > h) result.y = h;
  87.  
  88.       return result;
  89.     }
  90.  
  91.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  92.  
  93.   /** 
  94.    * Filter to keep at least a little bit of an object within the bounds
  95.    * of its parent.  This is set up assuming a top-left corner feature point.
  96.    *
  97.    * @param pt        the point to be filtered.
  98.    * @param limit_obj the object being limited.
  99.    * @param xsave     x amount to keep in bounds. 
  100.    * @param ysave     y amount to keep in bounds.
  101.    * @return Point the filtered point.
  102.    */
  103.   public static Point keep_in_parent(
  104.     Point      pt, 
  105.     interactor limit_obj, 
  106.     int        xsave,
  107.     int        ysave)
  108.     {
  109.       Point result = new Point(pt.x, pt.y);
  110.  
  111.       /* sanity check */
  112.       if (limit_obj == null || limit_obj.parent() == null)
  113.     return result;
  114.  
  115.       /* if we are too far above or to the left, fix that */
  116.       if (result.x < xsave - limit_obj.w()) result.x = xsave - limit_obj.w();
  117.       if (result.y < ysave - limit_obj.h()) result.y = ysave - limit_obj.h();
  118.  
  119.       /* if we are too far below or to the right, fix that */
  120.       if (result.x > limit_obj.parent().w() - xsave)
  121.         result.x = limit_obj.parent().w() - xsave;
  122.       if (result.y > limit_obj.parent().h() - ysave)
  123.         result.y = limit_obj.parent().h() - ysave;
  124.  
  125.       return result;
  126.     }
  127.  
  128.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  129.  
  130.   /** 
  131.    * Filter to limit points to line on a line segment. 
  132.    * 
  133.    * @param pt the point being filtered
  134.    * @param x1 x coordinate of first line segment end point
  135.    * @param y1 y coordinate of first line segment end point
  136.    * @param x2 x coordinate of second line segment end point
  137.    * @param y2 y coordinate of second line segment end point
  138.    * @return Point filtered point (which lies on the line segment)
  139.    */
  140.   public static Point limit_to_line_seg(
  141.     Point pt, 
  142.     int x1, int y1, 
  143.     int x2, int y2)
  144.     {
  145.       int dx, dy, C, A2B2, xc, yc;
  146.       float t;
  147.  
  148.       /* Calculate change in x & y across the line */
  149.       dx = x2 - x1;
  150.       dy = y2 - y1;
  151.  
  152.       /* Sanity check for well formed line */
  153.       if (dx == 0 && dy == 0)
  154.     /* not well formed, so don't filter */
  155.     return pt;
  156.  
  157.       /* For line passing through points x1,y1 and x2,y2, has the 
  158.        * equation Ax + By + C = 0 where:
  159.        *   A  = y2 - y1 = dy 
  160.        *   B  = -(x2 - x1) = -dx
  161.        *   C  = dx*y1 - dy*x1
  162.        *   dx = x2 - x1
  163.        *   dy = y2 - y1
  164.        *
  165.        * For a line with equation Ax + By + C = 0, the closest point on 
  166.        * the line to some arbitrary point x0, y0 is defined by:
  167.        *   xc = (B*B*x0 - A*B*y0 - A*C) / (A*A + B*B)
  168.        *   yc = (-A*B*x0 + A*A*y0 - B*C) / (A*A + B*B)
  169.        *
  170.        * So now we calculate the closest point on our line to the one given...
  171.        */
  172.        C = dx*y1 - dy*x1;
  173.        A2B2 = dy*dy + dx*dx;
  174.        xc = (dx*dx*pt.x + dy*dx*pt.y - dy*C) / A2B2;
  175.        yc = (dy*dx*pt.x + dy*dy*pt.y + dx*C) / A2B2;
  176.  
  177.        /* Parametric form of line equation is:
  178.     *  x = t*dx + x1
  179.     *  y = t*dy + y1
  180.     *
  181.     *  Compute t value to determine if we are past end points (t < 0 is 
  182.     *  before first end-point, t > 1 is beyond second end point).
  183.     */
  184.     if (dx != 0)
  185.       t = ((float)(xc - x1))/((float)dx);
  186.     else
  187.       t = ((float)(yc - y1))/((float)dy);
  188.  
  189.     /* clip to end points */
  190.     if (t <= 0.0)
  191.       return new Point(x1,y1);
  192.     else if (t >= 1.0)
  193.       return new Point(x2,y2);
  194.     else 
  195.       return new Point(xc,yc);
  196.     }
  197.  
  198.  
  199.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  200.  
  201.   // possible other functions to add later: limit to circle, scale
  202. }
  203. /*=========================== COPYRIGHT NOTICE ===========================
  204.  
  205. This file is part of the subArctic user interface toolkit.
  206.  
  207. Copyright (c) 1996 Scott Hudson and Ian Smith
  208. All rights reserved.
  209.  
  210. The subArctic system is freely available for most uses under the terms
  211. and conditions described in 
  212.   http://www.cc.gatech.edu/gvu/ui/sub_arctic/sub_arctic/doc/usage.html 
  213. and appearing in full in the lib/interactor.java source file.
  214.  
  215. The current release and additional information about this software can be 
  216. found starting at: http://www.cc.gatech.edu/gvu/ui/sub_arctic/
  217.  
  218. ========================================================================*/
  219.